package cn.iocoder.yudao.framework.business.captcha.service;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.business.basic.dao.repository.ObjectRedisRepository;
import cn.iocoder.yudao.framework.business.captcha.pojo.form.LegacyCaptchaDTO;
import cn.iocoder.yudao.framework.business.captcha.pojo.vo.LegacyCaptchaVO;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.framework.common.exception.KnownServiceException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.awt.*;

/**
 * 传统的图形验证码服务实现类。
 * 避坑指南：若使用了 captcha-plus 依赖，会与`com.xingyuv.captcha.service.CaptchaService`有同名冲突
 */
@Slf4j
@Service
public class LegacyCaptchaServiceImpl implements LegacyCaptchaService {
    private static final long CACHE_EXPIRE_SECONDS = 60L;
    private static final String CACHE_KEY_PREFIX = "xianmin:captcha:";

    @Resource
    private ObjectRedisRepository objectRedisRepository;

    @Override
    public LegacyCaptchaVO generate() {
        String numbers = RandomUtil.randomNumbers(4);
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(125, 43, 4, 80);
        lineCaptcha.setBackground(new Color(230, 244, 255));
        String base64 = ImgUtil.toBase64(lineCaptcha.createImage(numbers), ImgUtil.IMAGE_TYPE_JPG);
        LegacyCaptchaVO respVO = new LegacyCaptchaVO();
        respVO.setKey(UUID.fastUUID().toString(true));
        respVO.setImage("data:image/jpg;base64," + base64);
        objectRedisRepository.set(CACHE_KEY_PREFIX + respVO.getKey(), numbers, CACHE_EXPIRE_SECONDS);
        return respVO;
    }

    @Override
    public void verify(LegacyCaptchaDTO dto) throws KnownServiceException {
        Assertions.notBlank(dto.getKey(), "缺少验证码标识");
        Assertions.notBlank(dto.getCode(), "请输入正确验证码");
        String exceptCode = objectRedisRepository.get(CACHE_KEY_PREFIX + dto.getKey());
        Assertions.notBlank(exceptCode, "验证码已过期");
        Assertions.equals(dto.getCode(), exceptCode, "验证码错误");
        objectRedisRepository.delete(CACHE_KEY_PREFIX + dto.getKey());
    }

}
